package com.bwsoft.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.bwsoft.domain.Fun;
import com.bwsoft.domain.UserGroup;
import com.bwsoft.model.Message;
import com.bwsoft.service.FunService;

@Service(FunService.NAME)
public class FunServiceImpl extends BaseServiceImpl implements FunService {

	private static Logger log = Logger.getLogger(FunServiceImpl.class);

	private List<Fun> funs;

	@Override
	public List<Fun> getFunList() {
		List<Fun> funs = getFunListSortByOrder();
		List<Fun> funList=funs;
		funList = getSortList(funList, new ArrayList<Fun>());
		return funList;
	}

	/*
	 * 选出所有的根节点
	 */
	private List<Fun> getSortList(List<Fun> funList, List<Fun> sortFunList) {
		// 遍历菜单集合
		for (Fun fun : funList) {
			// 对一级菜单进行操作
			if (fun.getParentFunID() == 0) {
				// 查看是否有子节点
				Boolean isSon = hasSonTree(fun.getFunID(), funList);
				// 将这个对象插入对象容器中
				fun.setFunName("╠" + fun.getFunName());
				sortFunList.add(fun);
				// 如果该节点下仍有子节点开始递归
				if (isSon) {
					sortFunList = getSonTree(fun.getFunID(), sortFunList, funList);
				}
			}
		}

		return sortFunList;
	}

	/*
	 * 根据根节点再找根节点下的子节点
	 */
	private List<Fun> getSonTree(Integer faterID, List<Fun> sortFunList, List<Fun> funList) {

		for (Fun fun : funList) {

			// 遍历当前节点的父节点是传过来的节点ID的对象
			if (fun.getParentFunID().equals(faterID)) {

				// 该节点是否有子节点
				Boolean isSon = hasSonTree(fun.getFunID(), funList);

				// 按照层数，格式化名称
				String funName = "╠";
				for (int i = 1; i < fun.getLevelNum(); i++) {
					funName += " ═ ";
				}
				fun.setFunName(funName + fun.getFunName());

				// 将对象插入到容器中
				sortFunList.add(fun);

				// 其下是否有子元素，如果有责继续递归操作
				if (isSon) {
					sortFunList = getSonTree(fun.getFunID(), sortFunList, funList);
				}

			}
		}

		return sortFunList;
	}

	/*
	 * 查看在此集合有没有该funid的子元素
	 */
	public Boolean hasSonTree(Integer funID, List<Fun> funList) {

		Boolean flag = false;
		for (Fun fun : funList) {
			if (fun.getParentFunID().equals(funID)) {
				flag = true;
				break;
			}
		}
		return flag;
	}

	/**
	 * 得到所有功能的集合
	 */
	public List<Fun> getFunListSortByOrder() {

		funs = funDao.findAll();

		Collections.sort(funs, new Comparator<Fun>() {
			@Override
			public int compare(Fun f1, Fun f2) {
				return f1.getOrderNum().compareTo(f2.getOrderNum());
			}

		});
		return funs;
	}

	/**
	 * 添加菜单
	 */
	@Override
	@Transactional
	public Message addFun(Fun fun) {
		Message message=new Message();
		try {

			/* 得到该节点的层级数 */
			Integer levelNum = 0;
			if (fun.getParentFunID() == 0) {
				levelNum = 1;
			} else {
				levelNum = funDao.findById(fun.getParentFunID()).getLevelNum() + 1;
			}

			/* 得到该节点的OrderNum */
			int orderNum = ((Integer) funDao.findByHql("select max( a.orderNum) from Fun as a").get(0)) + 1;

			fun.setLevelNum(levelNum);
			fun.setOrderNum(orderNum);
			fun.setDelFlag(false);
			if (fun.getMenuFlag() == null) {
				fun.setMenuFlag(false);
			}
			funDao.save(fun);

			/* 将此功能为超级管理员绑定，超级管理员的ID 应为1 后续可能会有Bug 到时候看情况 */
			UserGroup ug = userGroupDao.findById(1);
			Set<Fun> funSet = ug.getFuns();
			funSet.add(fun);
			userGroupDao.saveOrUpdate(ug);
			message.setMsgFlag(true);
			message.setMsgStr("操作成功！");
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("添加菜单异常");
		}
		
		return message;
	}

	@Override
	@Transactional
	public boolean deleteFun(String idString) {
		Boolean flag = true;
		try {
			for (String id : idString.split(",")) {
				log.info("正在级联删除菜单 funID:" + id);
				funDao.delete(funDao.findById(Integer.parseInt(id)));
			}
			flag = true;
		} catch (Exception e) {
			log.error("删除菜单异常" + e);
			flag = false;
			throw new RuntimeException("删除菜单异常");
		}
		return flag;
	}

	@Override
	@Transactional
	public boolean updateFun(Fun fun) {

		Boolean flag = false;
		try {
			Fun f = funDao.findById(fun.getFunID());
			/* 得到该节点的层级数 */
			Integer levelNum = 0;
			if (fun.getParentFunID() == 0) {
				levelNum = 1;
			} else {
				levelNum = funDao.findById(fun.getParentFunID()).getLevelNum() + 1;
			}
			f.setParentFunID(fun.getParentFunID());
			f.setLevelNum(levelNum);
			f.setFunName(fun.getFunName());
			f.setFunIcon(fun.getFunIcon());
			f.setFunUrl(fun.getFunUrl());
			f.setDescription(fun.getDescription());
			f.setDelFlag(false);
			f.setMenuFlag(fun.getMenuFlag() == null ? false : fun.getMenuFlag() ? true : false);
			funDao.saveOrUpdate(f);
			flag = true;
		} catch (Exception e) {
			e.printStackTrace();
		}

		return flag;

	}

	/**
	 * 上移节点
	 */
	@Override
	public Message gotoUp(Integer funID) {
		Message msg=new Message();
		List<Fun> funs=getSameParentFun(funID);
		if(funs.get(0).getFunID().equals(funID)){
			msg.setMsgFlag(false);
			msg.setMsgStr("该节点已经是当前父节点的第一个节点，不能上移");
			return msg;
		}
		for(int i=1;i<funs.size();i++){
			if(funs.get(i).getFunID().equals(funID)){
				changeOrderNum(funID,funs.get(i-1).getFunID());
				msg.setMsgFlag(true);
			}
		}
		return msg;
	}
	/**
	 * 下移节点
	 */
	@Override
	public Message gotoDown(Integer funID) {
		Message msg=new Message();
		List<Fun> funs=getSameParentFun(funID);
		if(funs.get(funs.size()-1).getFunID().equals(funID)){
			msg.setMsgFlag(false);
			msg.setMsgStr("该节点已经是当前父节点的最后一个节点，不能下移");
			return msg;
		}
		for(int i=0;i<funs.size()-1;i++){
			if(funs.get(i).getFunID().equals(funID)){
				changeOrderNum(funID,funs.get(i+1).getFunID());
				msg.setMsgFlag(true);
			}
		}
		return msg;
	}
	
	/**
	 * 使两个节点的OrderNum 兑换
	 * @param funID 操作节点
	 * @param funID2 被换节点
	 */
	@Transactional
	private void changeOrderNum(Integer funID, Integer funID2) {
		Fun f1=funDao.findById(funID);
		Fun f2=funDao.findById(funID2);
		
		funDao.executeByHql("update Fun f set f.orderNum = ? where f.funID=?", f2.getOrderNum(),f1.getFunID());
		funDao.executeByHql("update Fun f set f.orderNum = ? where f.funID=?", f1.getOrderNum(),f2.getFunID());
	}

	@SuppressWarnings("unchecked")
	public List<Fun> getSameParentFun(Integer funID){
		List<Fun> funs=new ArrayList<Fun>();
		
		funs =funDao.findByHql("from Fun a where a.parentFunID=? and a.delFlag=0 order by a.orderNum", funDao.findById(funID).getParentFunID());
		return funs;
	}

	@Override
	public Fun findById(Integer funID) {
		return funDao.findById(funID);
	}
}
